﻿#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include"func.h"
#include"input.h"






typedef struct node {
	matrix data;
	node* next;

}node;
void menu(node* head);
node* input(node* head) {
	printf("输入增加的矩阵数量：\n");
	int n = nextInt();
	for (int i = 0; i < n; i++) {
		node* p = (node*)malloc(sizeof(node));
		p->data = input_matrix();
		p->next = head;
		head = p;
	}
	return head;
}

int output_all(node* head) {
	int i = 0;
	if (head == NULL) {

	}
	printf("输出矩阵：\n----------\n");
	for (node* p = head; p != NULL; p = p->next) {
		printf("矩阵%d:\n", i++);
		output_matrix(p->data);
		printf("----------\n");
	}
	return i - 1;
}

node* get_matrix(node* head, int index) {
	int i = 0;
	for (node* p = head; p != NULL; p = p->next, i++) {
		if (index == i) return p;
	}
	return NULL;
}

void free_list(node* head) {
	for (node* p = head; p != NULL; p = head) {
		head = head->next;
		free_matrix(p->data);
		free(p);
	}
}

void m2_m_menu(node* head, matrix(*op)(matrix, matrix)) {
	int len = output_all(head);
	int i, j;
	printf("输入第一个矩阵的索引：\n");
	i = nextInt();
	if (i < 0 || i > len) {
		printf("索引超出范围！\n");
		return;
	}
	printf("输入第二个矩阵的索引：\n");
	j = nextInt();
	if (j < 0 || j > len) {
		printf("索引超出范围！\n");
		return;
	}
	matrix ret = op(get_matrix(head, i)->data, get_matrix(head, j)->data);
	printf("结果矩阵:\n");
	output_matrix(ret);
	free_matrix(ret);
}

void m_m_menu(node* head, matrix(*op)(matrix)) {
	int len = output_all(head);
	int i;
	printf("输入矩阵的索引：\n");
	i = nextInt();
	if (i < 0 || i > len) {
		printf("输入的索引无效！\n");
		return;
	}
	matrix ret = op(get_matrix(head, i)->data);
	printf("结果矩阵:\n");
	output_matrix(ret);
	free_matrix(ret);
}

void md_m_menu(node* head, matrix(*op)(matrix, double)) {
	int len = output_all(head);
	int i;
	double num;
	printf("输入矩阵的索引：\n");
	i = nextInt();
	if (i < 0 || i > len) {
		printf("索引无效！\n");
		return;
	}
	printf("输入常数：\n");
	num = nextDouble();
	matrix ret = op(get_matrix(head, i)->data, num);
	printf("结果矩阵:\n");
	output_matrix(ret);
	free_matrix(ret);
}

void m_d_menu(node* head, double(*op)(matrix)) {
	int len = output_all(head);
	int i;
	printf("输入矩阵的索引：\n");
	i = nextInt();
	if (i < 0 || i > len) {
		printf("输入的索引无效！\n");
		return;
	}
	double ret = op(get_matrix(head, i)->data);
	printf("结果：%lf\n", ret);
}
void menu3(node* head) { m2_m_menu(head, add_matrix); }
void menu4(node* head) { m2_m_menu(head, sub_matrix); }
void menu5(node* head) { md_m_menu(head, mul_num); }
void menu6(node* head) { m2_m_menu(head, mul_matrix); }
void menu7(node* head) { m_m_menu(head, trans_matrix); }
void menu8(node* head) { m_m_menu(head, inv_matrix); }
void menu9(node* head) { m_d_menu(head, det); }


node* menu10(node* head) {
	system("cls");
	int len = output_all(head);
	if (len < 0) {
		printf("无矩阵\n");
		return NULL;
	}
	int idx;
	for (;;) {
		printf("输入删除的矩阵的索引：\n");
		idx = nextInt();
		if (idx < 0 || idx > len) {
			printf("索引无效！\n");
			continue;
		}
		break;
	}
	if (idx == 0) {
		node* temp = head;
		head = head->next;
		free_matrix(temp->data);
		free(temp);
	}
	else {
		node* prev = get_matrix(head, idx - 1);
		node* current = prev->next;
		prev->next = current->next;
		free_matrix(current->data);
		free(current);
	}

	printf("删除完成。\n");
	output_all(head);
	return head;
}

int main() {
	node* head = NULL;
	menu(head);
	free_list(head);
	return 0;
}

void menu(node* head) {
	for (;;) {
		system("cls");
		printf("矩阵运算\n");
		printf("--------------------\n");
		printf("1.输入矩阵\n");
		printf("2.输出矩阵\n");
		printf("3.求两个矩阵加\n");
		printf("4.求两个矩阵减\n");
		printf("5.求矩阵乘常数\n");
		printf("6.求矩阵乘矩阵\n");
		printf("7.求矩阵的转置\n");
		printf("8.求矩阵的逆\n");
		printf("9.求矩阵的行列式\n");
		printf("10.删除编号对应矩阵\n");
		printf("0.退出\n");
		printf("--------------------\n");
		printf("输入选项：");
		int op = nextInt();

		switch (op) {
		case 0:
			return;
		case 1:
			head = input(head);
			break;
		case 2:
			output_all(head);
			break;
		case 3:
			menu3(head);
			break;
		case 4:
			menu4(head);
			break;
		case 5:
			menu5(head);
			break;
		case 6:
			menu6(head);
			break;
		case 7:
			menu7(head);
			break;
		case 8:
			menu8(head);
			break;
		case 9:
			menu9(head);
			break;
		case 10:
			head = menu10(head);
			break;
		default:
			break;
		}

		system("pause");
	}
}
